package ru.averta.notes.domain.abstr;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.search.annotations.DocumentId;

import javax.persistence.*;
import java.util.UUID;

@MappedSuperclass
/*
 * Метод equals и id реализован согласно статье http://onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html?page=1
 */
public abstract class AbstractPersistentObject implements BusinessObject {

    @Id
    @DocumentId
    @GeneratedValue(generator = "fakeGenerator")
    @GenericGenerator(name = "fakeGenerator", strategy = "ru.averta.notes.dao.impl.FakeGenerator")
    @Column(name = "ID")
    private long id;

    @Transient 
    private final long fakeId = UUID.randomUUID().getMostSignificantBits();

    public final long getFakeId() {
        return fakeId;
    }

    public long getId() {
       return (id == 0) ? fakeId : id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || !(o instanceof BusinessObject)) {
            return false;
        }

        BusinessObject other = (BusinessObject) o;

        /* Т.к. ID мы генерируем уже при создании объекта в памяти,
         то мы можем его использовать для реализации equals
        // if the id is missing, return false
        if (id == 0) {
            return false;
        }
         */

        // equivalence by id
        return this.getId() == other.getId();
    }

    @Override
    public int hashCode() {
        if (this.getId() != 0) {
            return Long.valueOf(this.getId()).hashCode();
        } else {
            return super.hashCode();
        }
    }

    @Override
    public String toString() {
        return this.getClass().getName() + "[id=" + this.getId() + "]";
    }
}
